package com.bijava.utils;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author bijava
 * @version 1.0
 * @since 2020-03-20
 */
public class LoggerFactoryUtil {
    /**
     * 获得日志，自动判定日志发出者
     * @return
     */
    public static Logger get() {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        return LoggerFactory.getLogger(stackTrace[2].getClassName());
    }

    /**
     * 获取线程名、方法名称
     * @return
     */
    public static String template(){
        String threadName = Thread.currentThread().getName();
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        String methodName = stackTrace[3].getMethodName();

        return format("当前线程[{}]-当前方法[{}]",threadName,methodName);
    }

    /**
     * Trace等级日志，小于Debug
     * @param log 日志对象
     * @param format 格式文本，{} 代表变量
     * @param arguments 变量对应的参数
     */
    public static void trace(Logger log, String format, Object... arguments) {
        StringBuilder builder = new StringBuilder();
        builder.append(template()).append(format);
        log.trace(builder.toString(), arguments);
    }

    /**
     * Debug等级日志，小于Info
     * @param log 日志对象
     * @param format 格式文本，{} 代表变量
     * @param arguments 变量对应的参数
     */
    public static void debug(Logger log, String format, Object... arguments) {
        StringBuilder builder = new StringBuilder();
        builder.append(template()).append(format);
        log.debug(builder.toString(), arguments);
    }

    /**
     * Info等级日志，小于Warn
     * @param log 日志对象
     * @param format 格式文本，{} 代表变量
     * @param arguments 变量对应的参数
     */
    public static void info(Logger log, String format, Object... arguments) {
        StringBuilder builder = new StringBuilder();
        builder.append(template()).append(format);
        log.info(builder.toString(), arguments);
    }

    /**
     * Warn等级日志，小于Error
     * @param log 日志对象
     * @param format 格式文本，{} 代表变量
     * @param arguments 变量对应的参数
     */
    public static void warn(Logger log, String format, Object... arguments) {
        StringBuilder builder = new StringBuilder();
        builder.append(template()).append(format);
        log.warn(builder.toString(), arguments);
    }

    /**
     * Warn等级日志，小于Error
     * @param log 日志对象
     * @param e 需在日志中堆栈打印的异常
     * @param format 格式文本，{} 代表变量
     * @param arguments 变量对应的参数
     */
    public static void warn(Logger log, Throwable e, String format, Object... arguments) {
        StringBuilder builder = new StringBuilder();
        builder.append(template()).append(format);
        log.warn(format(builder.toString(), arguments), e);
    }

    /**
     * Error等级日志
     * @param log 日志对象
     * @param format 格式文本，{} 代表变量
     * @param arguments 变量对应的参数
     */
    public static void error(Logger log, String format, Object... arguments) {
        StringBuilder builder = new StringBuilder();
        builder.append(template()).append(format);
        log.error(builder.toString(), arguments);
    }

    /**
     * Error等级日志
     * 由于动态获取Logger，效率较低，建议在非频繁调用的情况下使用！！
     * @param log 日志对象
     * @param e 需在日志中堆栈打印的异常
     * @param format 格式文本，{} 代表变量
     * @param arguments 变量对应的参数
     */
    public static void error(Logger log, Throwable e, String format, Object... arguments) {
        StringBuilder builder = new StringBuilder();
        builder.append(template()).append(format);
        log.error(format(builder.toString(), arguments), e);
    }

    /**
     * 格式化文本
     * @param template 文本模板，被替换的部分用 {} 表示
     * @param values 参数值
     * @return 格式化后的文本
     */
    private static String format(String template, Object... values) {
        return String.format(template.replace("{}", "%s"), values);
    }
}